//
//  WBStatusListViewModel.swift
//  Weibo
//
//  Created by cc on 9/18/17.
//  Copyright © 2017 cc. All rights reserved.
//

import Foundation
import SDWebImage

/// 微博數據列表視圖模型

/*
    父類的選擇
 
 ﹣ 如果類需要使用 `KVC` 或 字典轉模型構架設置對象值，類就需要繼承自 NSObject
 ﹣ 如果類只是包裝一些代碼邏輯(寫一些函數)，可以不用任何父類，好處： 更加輕量級
 ﹣ 提示： 如果是 OC寫的，一律繼承自 NSObject 即可
    
    使命： 負責微博的數據處理
    1. 字典轉模型
    2. 上拉， 下拉 刷新的數據處理
 */


/// 上拉刷新最大尝试次数
private var maxPullupTryTimes = 3

class WBStatusListViewModel {
    
    
    /// 微博视图模型數組懶加載
    lazy var statusList = [WBStatusViewModel]()
    
    
    /// 上拉刷新错误次数
    private var pullupErrorTimes = 0
    
    
    /// 加載微博列表
    /// - pullup: 是否上拉刷新標記
    /// - Parameter completion: 完成回調[網絡請求是否成功, 是否刷新表格]
    func loadStatus(pullup: Bool,  completion: @escaping (_ isSuccess: Bool,_ shouldRefresh: Bool)->() ) {
        
        
        //判断是否是上拉刷新，同时检查刷新错误
        if pullup && pullupErrorTimes > maxPullupTryTimes {
            completion(true, false)
            return
        }
        
        
        //since_id   取出數組中第一條微博的id
        let since_id = pullup ? 0 : (statusList.first?.status.id ?? 0)
        
        //上拉刷新， 取出數組的最後一條微博的id
        let max_id = !pullup ? 0 : (statusList.last?.status.id ?? 0)
        
        //让数据访问层加载数据
        WBStatusListDAL.loadStatus(since_id: since_id, max_id: max_id) { (list, isSuccess) in
            
//        }
//        //发起网络请求，加载微博数据[字典的数组]
//        WBNetworkManager.shared.statusList(since_id: since_id, max_id: max_id ) { (list, isSuccess) in
            
//            //0.判断网络请求是否成功，如果失败，直接执行完成回调
//            if !isSuccess {
//                completion(false,false)
//                return
//            }
//            //1.  字典轉模型（第三方框架都支持嵌套的字典转模型）
//            // 1>定义结果可变数组
//            var array = [WBStatusViewModel]()
//            // 2> 遍历服务器返回的字典数组，字典转模型
//            for dict in list ?? [] {
//                //a) 创建微博模型  - 如果模型创建失败，继续后续的遍历
//                guard let model = WBStatus.yy_model(with: dict) else {
//                    continue
//                }
//                //b) 将 视图模型 添加到数组
//                array.append(WBStatusViewModel(model: model))
//            }
            
            
            //0.判断网络请求是否成功，如果失败，直接执行完成回调
            if !isSuccess {
                completion(false,false)
                return
            }
            
            //1. 遍历字典数组， 字典转模型 => 视图模型， 将视图模型添加到数组
            var array = [WBStatusViewModel]()
            for dict in list ?? [] {
            
//                print(dict["pic_urls"])
                
                //1>创建微博模型
                let status = WBStatus()
                
                //2>使用字典设置模型数值
                status.yy_modelSet(with: dict)
                
                //3>使用`微博` 模型创建 `微博视图` 模型
                let viewModel = WBStatusViewModel(model: status)
                
                //4> 添加到数组
                array.append(viewModel)
            }
            
            //视图模型创建完成
//            print(array)
            
            print("--刷新了 \(array.count)  條數據  -- \(array)")
            
            //2. 拼接數據
            if pullup {
                // 上拉刷新结束后，将结果拼接在数组的末尾
                self.statusList += array
            } else {
                //下拉刷新，应该将结果数组拼接在数组前面
                self.statusList = array + self.statusList
            }
        
            
            //3.判断上拉刷新的数据量
            if pullup && array.count == 0 {
                self.pullupErrorTimes += 1
                completion(isSuccess, false)
            } else {
                
                self.cacheSingleImage(list: array, finished: completion )
                //4. 真正有數據的回調
//                 completion(isSuccess, true)
            }
            
        }
    }
    
    
    /// 緩存本次下載微博數據數組中的單張圖像
    /// - 應該緩存完成單張圖片，並且修改過配圖的大小之後，再回調，才能保證表格等比例顯示單張圖像
    /// - Parameter list: 本次下載的視圖模型數組
    private func cacheSingleImage(list: [WBStatusViewModel], finished: @escaping (_ isSuccess: Bool,_ shouldRefresh: Bool)->() ) {
        
        //調度組
        let group = DispatchGroup()
        
        
        /// 記錄數據長度
        var length = 0
        
        //遍歷數組，查找微博數據中有單張圖像的，進行緩存
        for vm in list {
            
            //1>判斷圖像數量
            if vm.picUrls?.count != 1 {
                continue
            }
            
            //2.獲取圖像模型，代碼執行到這，數組中有且只有一張圖片
            guard let pic = vm.picUrls?[0].thumbnail_pic, let url = URL(string: pic) else{
                continue
            }
            
//            print("緩存的圖像\(url)")
            
            //3.下載圖像
            //1）loadImage 是sdWebImage的核心方法
            //2）圖像下載完成之後，會自動保存到沙盒中，文件路徑是url的md5
            //3）如果沙盒中已經存在緩存的圖像，後續使用SD通過URL加載的圖像，都會加載本地沙盒圖像
            //4）不會再次發起網絡請求，同時，回調方法同樣會調用
            //5）方法還是同樣的方法，調用還是同樣的調用，不過內部不會再次發起網絡請求。
            //// 注意點： 如果要緩存的圖像累計很大，找後臺要接口
            
            //A> 調度組 入組
            group.enter()
            
            SDWebImageManager.shared().loadImage(with: url, options: [], progress: nil, completed: { (image, _, _, _, _, _) in
                //將圖像轉換成二進制數據
                if let image = image , let data = UIImagePNGRepresentation(image) {
                    //NSData 是 length 屬性
                    length += data.count
                    
                    //圖像緩存成功，更新視圖配圖的大小
                    vm.updateSingleImageSize(image: image)
                    
                    
                }
//                print("緩存的圖像是\(image) ，長度是\(length)")
                
                // B> 調度組 出組  --- -定要放在回調函數的最後面一句
                group.leave()
            })
        }
        
        // C> 監聽調度組情況
        group.notify(queue: DispatchQueue.main) {
            print(" 圖像緩存完成 -- \(length / 1024)K")
            
            // 執行閉包回調
            finished(true, true)
        }
    
    }
    
}
